package com.epam.debrecen.hackathon.ai.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;

public class Regions {

	private final Map<String, Region> regions;

	public Regions() {
		this.regions = new HashMap<String, Region>();
	}

	public void addRegion(Region region) {
		this.regions.put(region.getName(), region);
	}

	public void addNeighbour(String name, Region neighbour) {
		this.addNeighbour(this.regions.get(name), neighbour);
	}

	public void addNeighbour(Region region, Region neighbour) {
		Region currentRegion = this.regions.get(region.getName());
		currentRegion.addNeighbour(neighbour);
		this.regions.put(currentRegion.getName(), currentRegion);
	}

	public Region getRegionByName(String name) {
		return this.regions.get(name);
	}

	public List<Region> getRegionList() {
		List<Region> result = new ArrayList<Region>();
		Iterator<String> iterator = this.regions.keySet().iterator();
		while (iterator.hasNext()) {
			result.add(this.regions.get(iterator.next()));
		}
		return result;
	}

	public List<Region> getFreeNeighbourList(String name) {
		Region currentRegion = this.regions.get(name);
		List<Region> result = new ArrayList<Region>();
		for (int i = 0; i < currentRegion.getNeighbours().size(); i++) {
			Region neighbour = this.getRegionByName(currentRegion.getNeighbours().get(i).getName());
			if (neighbour.getOwner() == null && !neighbour.isBishopProtected() && !neighbour.isUnderSiege()) {
				result.add(neighbour);
			}
		}
		return result;
	}

	public int getFreeNeighbouringRegionCount(String name) {
		Region currentRegion = this.regions.get(name);
		int result = 0;
		for (int i = 0; i < currentRegion.getNeighbours().size(); i++) {
			if (this.getRegionByName(currentRegion.getNeighbours().get(i).getName()).getOwner() == null) {
				result++;
			}
		}
		return result;
	}

	public int getNeighbourCount(String name) {
		return this.regions.get(name).getNeighbours().size();
	}

	public List<Region> getRegionsWithMostFreeNeighbours() {
		Map<Integer, List<String>> freeNeighbourMap = new HashMap<Integer, List<String>>();

		int max = -1;

		Region b = this.getBishopProtectedRegion();

		Iterator<String> iterator = this.regions.keySet().iterator();
		while (iterator.hasNext()) {
			String currentRegionName = iterator.next();
			int currentFreeNeighboursCount = this.getFreeNeighbouringRegionCount(currentRegionName);

			if (freeNeighbourMap.keySet().isEmpty()) {
				max = currentFreeNeighboursCount;
			}
			if (freeNeighbourMap.get(currentFreeNeighboursCount) == null) {
				freeNeighbourMap.put(currentFreeNeighboursCount, new ArrayList<String>());
			}

			if (this.getRegionByName(currentRegionName).getOwner() == null && !this.getRegionByName(currentRegionName).equals(b)) {
				freeNeighbourMap.get(currentFreeNeighboursCount).add(currentRegionName);

				if (currentFreeNeighboursCount > max) {
					max = currentFreeNeighboursCount;
				}
			}
		}

		List<Region> result = new ArrayList<Region>();

		for (int i = 0; i < freeNeighbourMap.get(max).size(); i++) {
			result.add(this.getRegionByName(freeNeighbourMap.get(max).get(i)));
		}

		return result;
	}

	/*
	 * public void setOwner(Region region, String player) {
	 * this.setOwner(region.getName(), player); }
	 */

	public void setOwner(String name, String player) {
		this.regions.get(name).setOwner(player);
	}

	public boolean isUnderSiege(String name) {
		return this.getRegionByName(name).isUnderSiege();
	}

	public void setUnderSiege(String name, boolean isUnderSiege) {
		this.getRegionByName(name).setUnderSiege(isUnderSiege);
	}

	public Region getRegionUnderSiege() {
		Iterator<String> iterator = this.regions.keySet().iterator();
		while (iterator.hasNext()) {
			Region currentRegion = this.getRegionByName(iterator.next());
			if (currentRegion.isUnderSiege()) {
				return currentRegion;
			}
		}
		return null;
	}

	public Region getBishopProtectedRegion() {
		Iterator<String> iterator = this.regions.keySet().iterator();
		while (iterator.hasNext()) {
			Region currentRegion = this.getRegionByName(iterator.next());
			if (currentRegion.isBishopProtected()) {
				return currentRegion;
			}
		}
		return null;
	}

	public Region getNextTarget() {
		List<Region> ownRegions = this.getOwnedRegions();
		if (ownRegions.isEmpty()) {
			return this.getRandomFreeRegion();
		} else {
			Random random = new Random();
			int index = random.nextInt(ownRegions.size());

			List<Region> freeNeighbourList = this.getFreeNeighbourList(ownRegions.get(index).getName());
			if (freeNeighbourList.isEmpty()) {
				return this.getRandomFreeRegion();
			}

			index = random.nextInt(freeNeighbourList.size());

			return freeNeighbourList.get(index);
		}
	}

	private Region getRandomFreeRegion() {
		List<Region> regionList = this.getRegionsWithMostFreeNeighbours();
		// choose randomly from them
		int index = new Random().nextInt((regionList.size() - 1) + 1);
		return regionList.get(index);
	}

	public List<Region> getOwnedRegions() {
		Iterator<String> iterator = this.regions.keySet().iterator();
		List<Region> result = new ArrayList<Region>();
		while (iterator.hasNext()) {
			String currentName = iterator.next();
			if (this.regions.get(currentName).getOwner() != null
					&& (this.regions.get(currentName).getOwner().equalsIgnoreCase("DEPAM") || this.regions.get(currentName).getOwner().equalsIgnoreCase("red"))) {
				result.add(this.getRegionByName(currentName));
			}
		}
		return result;
	}

	public void setBishopProtected(String name, boolean isBishopProtected) {

		Region b = this.getBishopProtectedRegion();

		if (b != null) {
			b.setBishopProtected(false);
		}

		this.getRegionByName(name).setBishopProtected(isBishopProtected);
	}
}
